package com.logicbus.dbcp.reload;

import com.alogic.load.Loader;
import com.alogic.reload.Reloader;
import com.alogic.reload.impl.Timestamp;
import com.anysoft.util.*;
import com.logicbus.dbcp.context.DbcpSource;
import com.logicbus.dbcp.core.ConnectionPool;
import com.logicbus.dbcp.sql.DBTools;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.w3c.dom.Element;

import java.sql.Connection;
import java.util.List;
import java.util.Map;

/**
 * SQL语句热加载
 *
 * @since 1.6.13.5 [20200605 duanyy]
 */
public class HotSQL extends Loader.Hot<Reloader>{
    /**
     * 上一次扫描时间
     */
    protected long lastScanTime = 0;

    /**
     * 数据库连接池id
     */
    protected String dbcpId = "default";

    /**
     * SQL语句
     */
    protected String sql;

    @Override
    public void configure(Properties p){
        sql = PropertiesConstants.getString(p,"sql","");
        dbcpId = PropertiesConstants.getString(p,"dbcpId","default");
        super.configure(p);
    }

    @Override
    public void configure(Element e, Properties p) {
        Properties props = new XmlElementProperties(e,p);
        configure(props);
    }

    @Override
    protected synchronized void doLoad(boolean first) {
        ConnectionPool pool = DbcpSource.getPool(dbcpId);
        if (pool == null){
            LOG.error("Can not find the dbcp pool:" + dbcpId);
            return ;
        }
        Connection conn = null;
        boolean error = false;
        try {
            conn = pool.getConnection();
            if (conn != null){
                List<Map<String,Object>> result = DBTools.listAsObject(conn,sql,lastScanTime);
                Factory<Reloader> f = new Factory<Reloader>();
                for (Map<String,Object> map:result){
                    String id = JsonTools.getString(map, "id", "");
                    if (StringUtils.isNotEmpty(id)){
                        Reloader loader = null;
                        try {
                            MapProperties props = new MapProperties(map,Settings.get());
                            loader = f.newInstance(Timestamp.class.getName(),props);
                            if (loader != null){
                                this.add(id,loader);
                            }
                        }catch (Exception ex){
                            LOG.error("Can not create loader.");
                        }
                    }
                }
                lastScanTime = System.currentTimeMillis();
            }else{
                LOG.error("Can not get a db connection from pool + " + dbcpId);
            }
        }catch (BaseException ex){
            error = true;
            LOG.error("Error when load from db:" + dbcpId);
            LOG.error(ExceptionUtils.getStackTrace(ex));
        }finally{
            pool.recycle(conn, error);
        }
    }

}
